// -*- c-basic-offset: 2 default-tab-width: 2 indent-tabs-mode: t -*-
// vim: autoindent tabstop=2 noexpandtab shiftwidth=2 softtabstop=2
//===------------ Symbol.cpp
//
//             This file is part of the reactor project
//                Author: R-Core Team
//
//===---------------------------------------------------------------------===//

#include "Symbol.h"

using namespace R;

int SymbolTable::size = 0;
Symbol** SymbolTable::table = NULL;

Symbol* SymbolTable::threeDots = NULL;

Symbol* Symbol::doNew(int length, char* label) {
  R_VAR(Symbol*, res);
  res = static_cast<Symbol*>(operator new(sizeof(Symbol), virtualVT));
  res->length = length;
  res->text = label;
  return res;
}

void SymbolTable::initializeSymbols(){
	Assert(table == NULL, "Symbol table is already initialized");
	table = new Symbol*[SYMTABLE_SIZE];

	// FIXME remove these casts
	threeDots = lookup(3, (char*)"...");
}

Symbol *SymbolTable::add(int len, char* label){
	Assert(table != NULL, "Symbol table must be initialized");

	rerror_on(size >= SYMTABLE_SIZE, "Symbol table to small");
	Symbol *sym = Symbol::doNew(len, label);
	table[size++] = sym;
	return sym;
}

Symbol *SymbolTable::lookup(int len, char* label){
	Assert(table != NULL, "Symbol table must be initialized");

	for(int i = 0; i < size ; i++){
		Symbol *sym = table[i];
		if(len == sym->length && !strncmp(sym->text, label, len))
			return sym;
	}
	return add(len, label);
}

Symbol *SymbolTable::lookup(char* label){ // Convenience method which need to be protected, etc ...
	Assert(table != NULL, "Symbol table must be initialized");

	for(int i = 0; i < size ; i++){
		Symbol *sym = table[i];
		if(!strncmp(sym->text, label, sym->length))
			return sym;
	}
	return add(strlen(label), label);
}
